home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
afloat.zip
/
FDIVIDE.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-03-15
|
3KB
|
151 lines
PAGE ,132
;----------------------------------------------------------
; FDIVIDE -- version for use with assembly language programs
;
; Copyright Bob Kline 1988
;
; Purpose:
; Divide two single-precision floating-point numbers.
;
; Input:
; DX:AX contain dividend in single-precision IEEE
; format; CX:BX contain divisor, same format.
;
; Output:
; Quotient (IEEE) single-precision real in DX:AX.
;
; Other registers affected:
; BX, CX, DI, SI, BP
;
; Procedures:
; None.
;
; Comments:
; Sets external variable _errno to ERANGE if over-
; flow occurs, or EDOM if an attempt is made to divide
; by zero. If a calling routine will be testing
; _errno, it must first reset the variable to zero
; to be sure that an error code is not left over
; from some previous call.
;----------------------------------------------------------
.MODEL SMALL
PUBLIC FDIVIDE
EXTRN _errno:WORD
EDOM EQU 33
ERANGE EQU 34
.CODE
FDIVIDE PROC
; check for division by zero
OR CX,CX
JNZ OK
OR BX,BX
JNZ OK
MOV _errno,EDOM
MOV AX,0FFFFh
MOV DX,0FF7Fh
RET
; get sign of result and save it
OK: MOV SI,DX
XOR DX,CX
AND DX,8000h
PUSH DX
MOV DX,SI
; subtract exponents, save result
MOV BP,CX
MOV DI,DX
SHL DX,1
SHL CX,1
XCHG DH,DL
XCHG CH,CL
XOR DH,DH
XOR CH,CH
SUB CX,127
SUB DX,127
SUB DX,CX
PUSH DX
MOV DX,DI
; unpack mantissas -- note that high word of divisor
; is now in BP so that we can use CX for shift count
AND DX,7Fh
AND BP,7Fh
OR DX,80h
OR BP,80h
; multiply DX:AX by BP:BX
MOV CX,26
XOR SI,SI
XOR DI,DI
JMP SHORT START
SHIFTS: SHL SI,1
RCL DI,1
RCL AX,1
RCL DX,1
START: CMP DX,BP
JB NOTYET
JA YES
CMP AX,BX
JB NOTYET
YES: SUB AX,BX
SBB DX,BP
INC SI
NOTYET: LOOP SHIFTS
MOV DX,DI
MOV AX,SI
; we divided either 1 or 2 places further than what we
; we will be able to use in the long run -- at least
; one more than necessary so that we can round the
; result -- if we wound up with 2 more places than
; needed shift right and increment the exponent, which
; we get back from the stack
POP BX
TEST DX,200h
JZ NO_EXTRA
SHR DX,1
RCR AX,1
INC BX
; shift out the extra place, noting first the discarded
; bit for rounding
NO_EXTRA:
MOV CX,AX
AND CX,1
SHR DX,1
RCR AX,1
ADD AX,CX
ADC DX,0
; remove the topmost bit -- it's understood
AND DX,7Fh
; restore exponent bias and test for range error
ADD BX,126
TEST BX,0FF00h
JZ INRANGE
MOV _errno,ERANGE
XOR BH,BH
; fold the exponent back into DX:AX
INRANGE:
XCHG BH,BL
SHR BX,1
OR DX,BX
; get back the sign bit
POP CX
OR DX,CX
RET
FDIVIDE ENDP
END